﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UM_SERVER.ProcessModel;
using UM_SERVER.Packet.InPacket.TalkMessage.Hole;
using UM_SERVER.Net;

namespace UM_SERVER.ProcessModel
{
    class ServerProcessModel :Model
    {
        public static void ProcessUserDigHole(DigHolePacket inpackage)
        {
            //得到好友对象
            User.User FriendUser = Globle.userManager.GetUser(inpackage.GetFriendUsername());
            //好友在线 --> 转发打洞请求
            if (FriendUser != null)
            {
                //得到请求者对象
                User.User user = Globle.userManager.GetUser(inpackage.GetUsername());
                //请求者在线
                if(user != null)
                {
                    //转发
                    RedirectUserHoleRequest(Encoding.Default.GetBytes(inpackage.GetUsername()), FriendUser, inpackage);
                    return;
                }
            }
            //回馈打洞失败请求
            
        }

        /// <summary>
        ///     转发用户的打洞请求
        /// </summary>
        /// <param name="username" type="byte[]">
        ///     <para>
        ///         申请者
        ///     </para>
        /// </param>
        /// <param name="friend" type="UM_SERVER.User.User">
        ///     <para>
        ///         被申请者对象
        ///     </para>
        /// </param>
        /// <param name="inpackage" type="UM_SERVER.Packet.InPacket.TalkMessage.Hole.DigHolePacket">
        ///     <para>
        ///         转发申请包
        ///     </para>
        /// </param>
        public static void RedirectUserHoleRequest(byte[] username, User.User friend, DigHolePacket inpackage)
        {
            Session.Session session = Globle.sessionManager.GetMemberByKey(friend.Username) as Session.Session;
            if(session != null)
            {
                byte[] UsernameLength = BitConverter.GetBytes(username.Length);
                byte[] packagebody = new byte[username.Length + 12];
                Offset = 0;
                Array.ConstrainedCopy(UsernameLength, 0, packagebody, Offset, 4);
                Offset += 4;
                Array.ConstrainedCopy(username, 0, packagebody, Offset, username.Length);
                Offset += username.Length;
                Array.ConstrainedCopy(inpackage.GetHolePort(), 0, packagebody, Offset, 4);
                Offset += 4;
                Array.ConstrainedCopy(inpackage.GetDigType(), 0, packagebody, Offset, 4);
                Offset += 4;
                byte[] protocol1 = ProtocolFactory.ProtocolFactory.ReGetProtocolToTalkMessage("RedirectDigHole",
                                                                          (int)Packet.Protocol.TALK_OUT_NetworkCommand.REDIRECT_HOLE,
                                                                          (int)Packet.Protocol.NetworkProtocol.TALK_MESSAGE,
                                                                          packagebody,
                                                                          ProtocolFactory.ProtocolFactory.ACK.Yes,
                                                                          ProtocolFactory.ProtocolFactory.ENCRYPT.No,
                                                                          session.SessionCode);
                NetControl.Send(protocol1, friend.TalkPort, friend.IpAddress);
            }
        }

        public static void ProcessAckDigHole(Ack_DigHolePacket inpackage)
        {
            User.User user = Globle.userManager.GetUser(inpackage.GetUsername());
            if(user != null)
            {
                Session.Session session = Globle.sessionManager.GetMemberByKey(user.Username) as Session.Session;
                if(session != null && !session.Exprid)
                { 
                    //向服务器发送打洞测试回馈
                    byte[] username = Encoding.Default.GetBytes(inpackage.GetUsername());
                    byte[] UsernameLength = BitConverter.GetBytes(username.Length);
                    byte[] FriendnameLength = BitConverter.GetBytes(inpackage.GetFriendname().Length);
                    byte[] packagebody = new byte[username.Length + inpackage.GetFriendname().Length + 16];
                    Offset = 0;
                    Array.ConstrainedCopy(UsernameLength, 0, packagebody, Offset, 4);
                    Offset += 4;
                    Array.ConstrainedCopy(username, 0, packagebody, Offset, username.Length);
                    Offset += username.Length;
                    Array.ConstrainedCopy(FriendnameLength, 0, packagebody, Offset, 4);
                    Offset += 4;
                    Array.ConstrainedCopy(inpackage.GetFriendname(), 0, packagebody, Offset, inpackage.GetFriendname().Length);
                    Offset += inpackage.GetFriendname().Length;
                    byte[] HolePort = BitConverter.GetBytes(inpackage.GetHolePort());
                    Array.ConstrainedCopy(HolePort, 0, packagebody, Offset, 4);
                    Offset += 4;
                    Array.ConstrainedCopy(inpackage.GetDigType(), 0, packagebody, Offset, 4);
                    Offset += 4;
                    byte[] protocol1 = ProtocolFactory.ProtocolFactory.ReGetProtocolToTalkMessage("ServerAckDigHole",
                                                                           (int)Packet.Protocol.TALK_OUT_NetworkCommand.SERVER_ACK_HOLE,
                                                                           (int)Packet.Protocol.NetworkProtocol.TALK_MESSAGE,
                                                                           packagebody,
                                                                           ProtocolFactory.ProtocolFactory.ACK.No,
                                                                           ProtocolFactory.ProtocolFactory.ENCRYPT.No,
                                                                           session.SessionCode);
                    NetControl.Send(protocol1, inpackage.GetHolePort(), user.IpAddress);
                }
            }
        }
    }
}
